package com.zjq.authoritysystem.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zjq.authoritysystem.entity.Permission;
import com.zjq.authoritysystem.entity.Role;
import com.zjq.authoritysystem.entity.User;
import com.zjq.authoritysystem.mapper.PermissionMapper;
import com.zjq.authoritysystem.mapper.UserMapper;
import com.zjq.authoritysystem.service.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zjq.authoritysystem.utils.MenuTreeUtil;
import com.zjq.authoritysystem.utils.PermissionTreeUtil;
import com.zjq.authoritysystem.vo.RolePermissionVo;
import com.zjq.authoritysystem.vo.query.PermissionQueryVo;
import com.zjq.authoritysystem.vo.query.RoleQueryVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @deacription: 描述
 * @className: PermissionServiceImpl
 * @author: BetOnMe
 * @since: 2023-09-20 15:44
 * @version: 1.0
 **/
@Slf4j
@Service
@Transactional
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Resource
    private UserMapper userMapper;

    @Override
    public List<Permission> findPermissionsByUserId(Integer userId) {
        return baseMapper.findPermissionsListByUserId(userId);
    }

    @Override
    public List<Permission> listByTreeModel(PermissionQueryVo permissionQueryVo) {
        List<Permission> list = this.list(new QueryWrapper<Permission>()
                .like(!ObjectUtils.isEmpty(permissionQueryVo.getLabel()), "label", permissionQueryVo.getLabel())
                .eq("is_delete", Permission.IS_DELETE_NO)
                .orderByDesc("sort"));
        List<Permission> permissions = PermissionTreeUtil.makeRolesTree(list, Permission.TYPE_MENU);
        return permissions;
    }

    @Override
    public Boolean checkPermissionHaveChildren(Integer id) {
        return this.list(new QueryWrapper<Permission>().eq("parent_id", id).eq("is_delete", Permission.IS_DELETE_NO)).size() > 0;
    }

    @Override
    public RolePermissionVo findPermissionTree(Integer userId, Integer roleId) {
        // 查询用户信息
        User user = userMapper.selectById(userId);
        List<Permission> permissions = null;
        // 判断用户角色，如果是管理员，则查询所有权限，如果不是管理员，则只查询自己所拥有的权限
        if (!ObjectUtils.isEmpty(user.getIsAdmin()) && user.getIsAdmin() == User.IS_ADMIN_YES) {
            // 查询所有权限
            permissions = this.list();
        } else {
            // 根据用户编号查询
            permissions = baseMapper.findPermissionsListByUserId(userId);
        }
        // 组成树形结构数据
        List<Permission> permissionsTree = MenuTreeUtil.makeMenuTree(permissions, Permission.PARENT_MENU_ID);
        // 查询要分配角色的原有权限
        List<Permission> rolePermissions = baseMapper.findPermissionsByRoleId(roleId);
        // 找出该角色存在的数据
        List<Integer> ids = new ArrayList<>();
        Optional.ofNullable(permissions).orElse(new ArrayList<>())
                .stream()
                .filter(Objects::nonNull)
                .forEach(item -> {
                    Optional.ofNullable(rolePermissions).orElse(new ArrayList<>())
                            .stream()
                            .filter(Objects::nonNull)
                            .forEach(obj -> {
                                // 判断两者数据id是否一致，如果一致，则表示拥有该权限
                                if (item.getId().equals(obj.getId())) {
                                    ids.add(obj.getId());
                                    return;
                                }
                            });
                });
        RolePermissionVo rolePermissionVo = new RolePermissionVo();
        rolePermissionVo.setPermissionList(permissionsTree);
        rolePermissionVo.setCheckList(ids.toArray());
        return rolePermissionVo;
    }

}
